package com.yanqu.road.server.gameplayer.module.activity.starlight;

import com.yanqu.road.entity.DataStatus;
import com.yanqu.road.entity.activity.ActivityDetail;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.starlight.StarLightMallRecord;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.language.LanguageType;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.logic.bussiness.activity.StarLightBusiness;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.logic.mail.MailManager;
import com.yanqu.road.server.manger.MultipleLanguageMgr;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.starlight.StarLightMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;

/**
 * @Author : Cxp
 * @Time : 2024-11-07
 * @Description :
 */

public class StarLightModule extends GeneralModule {
    private static Logger logger = LogManager.getLogger(StarLightModule.class.getName());

    List<StarLightMallRecord> mallRecords = new ArrayList<>(); // 商品记录

    public StarLightModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ActivityInfo activityInfo = StarLightMgr.getActivityInfo();
        if (ActivityMgr.activityInShowTime(activityInfo)) {
            mallRecords = StarLightBusiness.getMallRecordsByUserId(activityInfo.getActivityId(),
                    player.getUserId());
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        for (StarLightMallRecord record : mallRecords) {
            if (null != record) {
                if (record.isInsertOption()) {
                    StarLightBusiness.addMallRecord(record);
                } else if (record.isUpdateOption()) {
                    StarLightBusiness.updateMallRecord(record);
                }
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        activityReload();
    }

    /**
     * 重新加载活动，包括同步配置、初始化用户、同步用户
     */
    public void activityReload() {
        if (!SystemOpenMgr.systemOpen(player, eSystemId.StarLight.getValue())) {
            return;
        }

        ActivityInfo activityInfo = StarLightMgr.getActivityInfo();
        if (!ActivityMgr.activityInShowTime(activityInfo)) {
            return;
        }
        initMallRecord(activityInfo);
    }

    /**
     * 初始化商城礼包记录
     *
     * @param activityInfo activityInfo
     */
    private void initMallRecord(ActivityInfo activityInfo) {
        int activityId = activityInfo.getActivityId();
        Map<Integer, List<MallInfo>> infoMap = getMallInfoMapByType(activityId);
        boolean daily = true; // 是否每日补发
        for (List<MallInfo> mallInfos : infoMap.values()) { // 找到第一个商品判断它的限购类型
            for (MallInfo mallInfo : mallInfos) {
                // 一次判断活动所有商品是否每日限购，即LimitBuyType全1或全0
                if (mallInfo.getLimitBuyType() == eLimitBuyType.FOREVER.getValue()) {
                    daily = false;
                    break;
                }
            }
            if (!daily) {
                break;
            }
        }

        int length = daily ? ActivityHelper.getActivityDuration(activityInfo) - 1 : 1; // 每日限购需要产生多条记录
        for (int i = 1; i <= length; i++) {
            for (List<MallInfo> mallInfos : infoMap.values()) {
                mallInfos.sort(Comparator.comparingInt(MallInfo::getSort));
                for (MallInfo mallInfo : mallInfos) {
                    String price = mallInfo.getPrice();
                    int cost;
                    if (price.contains("=")) {
                        String[] items = mallInfo.getPrice().split("=");
                        cost = Integer.parseInt(items[1]);
                    } else {
                        cost = Integer.parseInt(price);
                    }
                    // 直到第一个付费礼包前的所有免费礼包都加入补发表
                    if (mallInfo.getRechargeId() == 0 && cost == 0) { // 免费，没有充值ID，就算要道具，道具数量为0
                        addMallRecord(i, mallInfo);
                    } else if (mallInfo.getCategory() == eMallCategory.StarLight.getValue()) { // 加强校验
                        break;
                    }
                }
            }
        }
    }

    /**
     * 根据类型划分礼包
     *
     * @param activityId 活动ID
     * @return 礼包分类 type -> 礼包
     */
    public Map<Integer, List<MallInfo>> getMallInfoMapByType(int activityId) {
        Map<Integer, Map<Integer, MallInfo>> allMallInfoMap = ActivityMgr.getAllActivityMallInfoMap();
        Map<Integer, MallInfo> mallInfoMap = allMallInfoMap.get(activityId);
        Map<Integer, List<MallInfo>> infoMap = new HashMap<>(); // 礼包页签分类 type -> 礼包
        for (MallInfo mallInfo : mallInfoMap.values()) {
            if (mallInfo != null) {
                String[] extendParam = mallInfo.getExtendParam().split("\\|");
                int type = Integer.parseInt(extendParam[0]);
                if (!infoMap.containsKey(type)) {
                    infoMap.put(type, new ArrayList<>());
                }
                infoMap.get(type).add(mallInfo);
            }
        }

        return infoMap;
    }

    /**
     * 不管活动是否结束都需要判断补发
     *
     * @return 星星点灯活动 ActivityInfo
     */
    public ActivityInfo getActivityInfo() {
        Map<Integer, ActivityDetail> activityDetailMap = NormalActivityMgr.getActivityDetailMap();
        for (ActivityInfo activityInfo : NormalActivityMgr.getAllActivityInfoMap().values()) {
            for (ActivityDetail detail : activityDetailMap.values()) {
                if (detail.getAutoSendRewardState() != 1 && activityInfo.getType() == eActivityType.StarLight.getValue()) {
                    return activityInfo;
                }
            }
        }
        return null;
    }

    /**
     * 每日补发
     */
    public void dailyReset() {
        ActivityInfo activityInfo = getActivityInfo();
        if (activityInfo == null) {
            return;
        }

        int activityId = activityInfo.getActivityId();
        if (mallRecords == null || mallRecords.isEmpty()) {
            return;
        }

        // 一次判断活动所有商品是否每日限购，即LimitBuyType全1或全0
        if (mallRecords.get(0).getBuyType() == eLimitBuyType.FOREVER.getValue()) {
            return;
        }

        Map<Integer, List<StarLightMallRecord>> dayRecordMap = new HashMap<>(); // 活动天数 -> 商城补发记录
        for (StarLightMallRecord record : mallRecords) {
            int activityDay = record.getActivityDay();
            if (!dayRecordMap.containsKey(activityDay)) {
                dayRecordMap.put(activityDay, new ArrayList<>());
            }
            dayRecordMap.get(activityDay).add(record);
        }

        Property reward = new Property();
        List<StarLightMallRecord> update = new ArrayList<>();
        Map<Integer, Map<Integer, MallInfo>> allActivityMallInfoMap = ActivityMgr.getAllActivityMallInfoMap();
        Map<Integer, MallInfo> mallInfoMap = allActivityMallInfoMap.get(activityId);
        int day = ActivityHelper.getWhichDayAfterBeginTime(activityInfo);
        for (int i = 1; i < day; i++) {
            if (dayRecordMap.containsKey(i)) {
                List<StarLightMallRecord> dayRecords = dayRecordMap.get(i);
                for (StarLightMallRecord dayRecord : dayRecords) {
                    if (dayRecord.getAcquireType() == 0) { // 补发记录存在未获得
                        reward.addProperty(PropertyHelper.parseStringToProperty(mallInfoMap.get(dayRecord.getMallId()).getReward()));
                        update.add(dayRecord);
                    }
                }
            }
        }

        if (update.isEmpty()) { // 没事别发邮件
            return;
        }

        for (StarLightMallRecord record : update) {
            record.setAcquireType(2);
            record.setAcquireTime(System.currentTimeMillis());
        }

        // 通用补发
        long userId = player.getUserId();
        UserInfo userInfo = UserMgr.getUserInfo(userId);
        String language = LanguageType.LANGUAGE_DEFAULT;
        if (null != userInfo) {
            language = userInfo.getLanguage();
        }
        String activityName = ServerLanguageMgr.getContent(activityInfo.getActivityName(), language);
        String mailTitle =
                StringUtils.format(MultipleLanguageMgr.getContent(MailManager.AUTO_SEND_ACTIVITY_CROSS_RANK_REWARD_TITLE, language), activityName);
        String mailContent =
                StringUtils.format(MultipleLanguageMgr.getContent(MailManager.AUTO_SEND_ACTIVITY_CROSS_RANK_REWARD_CONTENT, language), activityName);
        MailManager.sendMail(userId, eMailType.SYSTEM.getValue(), reward.toHelperString(), mailContent, mailTitle);
    }

    /**
     * 添加活动商城记录
     *
     * @param activityDay 活动开始天数
     * @param mallInfo    商品信息
     */
    public void addMallRecord(int activityDay, MallInfo mallInfo) {
        int mallId = mallInfo.getMallId();

        synchronized (this) {
            for (StarLightMallRecord record : mallRecords) {
                if (record.getActivityDay() == activityDay && record.getMallId() == mallId) {
                    return;
                }
            }

            StarLightMallRecord record = new StarLightMallRecord();
            record.setActivityId(mallInfo.getActivityId());
            record.setUserId(player.getUserId());
            record.setActivityDay(activityDay);
            record.setMallId(mallId);
            record.setAcquireType(0); // 获得方式 0-未获得 1-购买 2-补发
            record.setAcquireTime(System.currentTimeMillis());
            record.setBuyType(mallInfo.getLimitBuyType());
            record.setOp(DataStatus.Insert);
            mallRecords.add(record);
        }
    }

    /**
     * 购买物品时修改状态
     *
     * @param activityDay 活动开始天数
     * @param mallInfo    商品信息
     */
    public void modifyType(int activityDay, MallInfo mallInfo, int type) {
        int mallId = mallInfo.getMallId();
        for (StarLightMallRecord record : mallRecords) {
            if (record.getActivityDay() == activityDay && record.getMallId() == mallId) {
                record.setAcquireType(type);
                record.setAcquireTime(System.currentTimeMillis());
            }
        }
    }
}
